import { LogMgr } from "db://assets/scripts/platform/log/LogMgr"
import { Game_2048_MergeDirection, Game_Status } from "../../../common/enums"
import { Game2048Model } from "../Game2048Model"
import { LevelScript_2048 } from "../LevelScript_2048"
import { PlayerData } from "../../../data/player/PlayerData"
import { GlobalEventMgr } from "../../../../platform/event/GlobalEventMgr"
import { GlobalEventTyp } from "../../../common/GlobalEventType"

export class LevelScript_2048_0 extends LevelScript_2048{

    constructor(data:Game2048Model) {
        super(data)
    }

    //初始化游戏
    initGame() {
        let data = this.data
        data.nowPoint = 0
        data.moveTotalTimes = 0
        data.totalTime = 0
        data.randomTimes = 0
        data.directionTimes = new Map()
        this.boardInit()

        data.gameState = Game_Status.Init
    }

    //开始游戏
    startGame() {
        this.data.gameState = Game_Status.Playing
    }

    //暂停游戏 
    pauseGame() {
        this.data.gameState = Game_Status.Pause
    }

    //继续游戏
    reuseGame() {
        this.data.gameState = Game_Status.Playing
    }

    //结束游戏
    endGame() {
        //
        this.data.gameState = Game_Status.End
        //记录数据
        let info = PlayerData.ins.game2048.levelInfos.get(this.data.level)
        info.playedNum+=1
        GlobalEventMgr.ins.emit(GlobalEventTyp.GameLevelPlayNumChange)
        if(this.data.nowPoint > info.maxScore){
            info.maxScore = this.data.nowPoint
        }
        PlayerData.ins.game2048.saveData()
    }

    boardInit() {
        let data = this.data
        for (let i = 0; i < 4; i++) {
            let row = data.boardData[i]
            if (!row) {
                row = []
                data.boardData[i] = row
            }
            for (let j = 0; j < 4; j++) {
                data.boardData[i][j] = 0
            }
        }
        //随机2，4
        let randomNum1 = Math.random() < 0.9 ? 2 : 4
        let randomNum2 = Math.random() < 0.9 ? 2 : 4
        //0~3
        let row1 = Math.floor(Math.random() * 4)
        let col1 = Math.floor(Math.random() * 4)

        let row2 = (row1 + 2) % 3
        let col2 = (col1 + 2) % 3
        data.boardData[row1][col1] = randomNum1
        data.boardData[row2][col2] = randomNum2
    }

    merge(direction: number) {
        //TODO 可以非相邻进行合并
        let mergeSuccess = false
        switch (direction) {
            case Game_2048_MergeDirection.Up:
                mergeSuccess = this.mergeUp()
                break;
            case Game_2048_MergeDirection.Down:
                mergeSuccess = this.mergeDown()
                break;
            case Game_2048_MergeDirection.Left:
                mergeSuccess = this.mergeLeft()
                break;
            case Game_2048_MergeDirection.right:
                mergeSuccess = this.mergeRight()
                break;
        }
        if(mergeSuccess){
            let old =this.data.directionTimes.get(direction)
            old = old?old+1:0
            this.data.directionTimes.set(direction,old+1)
        }
        this.mergeCheck()
        let pos = this.randomNewChess()
        return pos
    }
    mergeCheck() {
        //检测棋子中是否有目标
        let boardData = this.data.boardData
        let row = this.data.row
        let col = this.data.col
    out:for (let i = 0; i < row; i++) {
            for (let j = 0; j < col; j++) {
                let el = boardData[i][j]
                if(el>=1024){
                    this.data.passed = true
                    break out
                }
            }
        }
        let end = true;
        //检测是否结束
    out:for (let i = 0; i < row; i++) {
            for (let j = 0; j < col; j++) {
                let nowPosNum = boardData[i][j]
                if (nowPosNum===0) {
                    end = false
                    break out;
                }
                //与同列向下最近一个不是0的数进行比较
                for(let k = i+1;k<row;k++){
                    let nexRowNum = boardData[k][j]
                    if(nexRowNum===0){
                        continue
                    }
                    if(nowPosNum===nexRowNum){
                        end = false
                        break out;
                    }else{
                        break
                    }
                }
                //与同行向右最近一个不是0的进行比较
                for(let k = j+1;k<col;k++){
                    let nexColNum = boardData[i][k]
                    if(nexColNum===0){
                        continue
                    }
                    if(nowPosNum===nexColNum){
                        end = false
                        break out;
                    }else{
                        break
                    }
                }
            }
        }
        if(end){
            this.endGame()
        }
    }
    randomNewChess() {
        let randomNum1 = Math.random() < 0.9 ? 2 : 4
        let data = this.data.boardData
        let m = this.data
        let poses = []
        for (let i = 0; i < m.row; i++) {
            for (let j = 0; j < m.col; j++) {
                const element = data[i][j];
                if(element == 0) {
                    poses.push([i,j])
                }
            }   
        }
        if(poses.length == 0){
            return []
        }
        let randomIndex = Math.floor(Math.random()*poses.length)
        let pos = poses[randomIndex]
        data[pos[0]][pos[1]] = randomNum1
        return pos
    }
    mergeUp() {
        let data = this.data.boardData
        let row = this.data.row
        let col = this.data.col
        LogMgr.debug("向上合并")
        let result = false;
        for (let index = 0; index < col; index++) {//列遍历
            let colData = []
            for (let i = 0; i < row; i++) {
                if(data[i][index] == 0) {
                    continue;
                }
                colData.push(data[i][index])
            }
            for (let i = 0; i < colData.length-1; i++) {
                let  d1 = colData[i];
                let d2 = colData[i+1];
                if(d1!=0 && d1===d2){
                    d1 *=2
                    this.mergeSuccessHandle(d1)
                    d2 = 0
                    colData[i] = d1
                    colData[i+1] = d2
                    result = true
                }
            }
            colData = colData.filter((item) => item != 0)
            for (let i = 0; i < row; i++) {
                data[i][index] = colData[i]?colData[i]:0
            }
        }
        return result
    }
    mergeSuccessHandle(sucNum: any) {
        let old = this.data.numberTimes.get(sucNum)
        if(!old){
            old=0
        }
        this.data.numberTimes.set(sucNum, old+1)
        this.data.nowPoint+=sucNum
    }
    mergeDown() {
        LogMgr.debug("向下合并")
        let result = false;
        let data = this.data.boardData
        let row = this.data.row
        let col = this.data.col
        for (let index = 0; index < col; index++) {//列遍历
            let colData = []
            for (let i = 0; i < row; i++) {
                if(data[i][index] == 0) {
                    continue;
                }
                colData.push(data[i][index])
            }
            for (let i = colData.length-1; i >0 ; i--) {
                let  d1 = colData[i];
                let d2 = colData[i-1];
                if(d1!=0 && d1===d2){
                    d1 *=2
                    this.mergeSuccessHandle(d1)
                    d2 = 0
                    colData[i] = d1
                    colData[i-1] = d2
                    result = true
                }
            }
            colData = colData.filter((item) => item != 0)
            let colIndex = colData.length-1
            for (let i = row-1; i >=0; i--) {
                data[i][index] = colData[colIndex]?colData[colIndex]:0
                colIndex--
            }
        }
        return result
    }
    mergeLeft() {
        LogMgr.debug("向左合并")
        let result = false;
        let data = this.data.boardData
        let row = this.data.row
        let col = this.data.col
        for (let index = 0; index < row; index++) {//行
            let rowData = []
            for (let i = 0; i < col; i++) {
                if(data[index][i] == 0) {
                    continue;
                }
                rowData.push(data[index][i])
            }
            for (let i = 0; i < rowData.length-1; i++) {
                let  d1 = rowData[i];
                let d2 = rowData[i+1];
                if(d1!=0 && d1===d2){
                    d1 *=2
                    this.mergeSuccessHandle(d1)
                    d2 = 0
                    rowData[i] = d1
                    rowData[i+1] = d2
                    result = true
                }
            }
            rowData = rowData.filter((item) => item != 0)
            for (let i = 0; i < col; i++) {
                data[index][i] = rowData[i]?rowData[i]:0
            }
        }
        return result
    }

    mergeRight() {
        LogMgr.debug("向右合并")
        let result = false;
        let data = this.data.boardData
        let row = this.data.row
        let col = this.data.col
        for (let index = 0; index < row; index++) {//行遍历
            let rowData = []
            for (let i = 0; i < col; i++) {
                if(data[index][i] == 0) {
                    continue;
                }
                rowData.push(data[index][i])
            }
            for (let i = rowData.length-1; i >0 ; i--) {
                let  d1 = rowData[i];
                let d2 = rowData[i-1];
                if(d1!=0 && d1===d2){
                    d1 *=2
                    this.mergeSuccessHandle(d1)
                    d2 = 0
                    rowData[i] = d1
                    rowData[i-1] = d2
                    result = true
                }
            }
            rowData = rowData.filter((item) => item != 0)
            let rowIndex = rowData.length-1
            for (let i = col-1; i >=0; i--) {
                data[index][i] = rowData[rowIndex]?rowData[rowIndex]:0
                rowIndex--
            }
        }
        return result
    }

    isEnd() {
        for (let index = 0; index < 4; index++) {

        }
        return false
    }
}